home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / dtype / fpvcd402.lha / Source / fastconvert.asm < prev    next >
Assembly Source File  |  1995-01-22  |  4KB  |  187 lines

  1. ******************************************************************************
  2. *
  3. * VOC Datatype, based on the sourcecode found in OS3.1 Native Developer Kit
  4. *
  5. * Written by Christian Buchner
  6. *
  7. ******************************************************************************
  8. * fastconvert.asm
  9.  
  10.         SECTION Code
  11.  
  12.  
  13. ; scaling of an ULONG given two ULONGS (68020 really needed)
  14. ; ==========================================================
  15.  
  16.         ; d0=source length
  17.         ; d1=source frequency
  18.         ; d2=destination frequency
  19.         ; ->d0=destination length
  20.  
  21.         XDEF _ScaleLength
  22.  
  23. _ScaleLength    move.l    d3,-(sp)
  24.         mulu.l    d2,d3:d0
  25.         divu.l    d1,d3:d0
  26.         move.l    (sp)+,d3
  27.         rts
  28.  
  29.  
  30. ; 8 bit unsigned MONO -> 8 bit signed MONO conversion/stretching
  31. ; ==============================================================
  32.  
  33.         ; a0=source
  34.         ; a1=destination
  35.         ; d0=destination length
  36.         ; d1=source frequency
  37.         ; d2=destination frequency
  38.  
  39.         XDEF _ConvertMono8
  40.  
  41. _ConvertMono8    cmp.l    d1,d2
  42.         beq.s    quickloopm8
  43.  
  44.         ; source and destination frequency differ
  45.         ; use a scaling conversion loop
  46.  
  47.         movem.l    d3/d4/d5,-(sp)    ; save registers
  48.  
  49.         move.l    d1,d4        ; calc skip value in d4
  50.         moveq    #0,d1        ; d4=d1/d2
  51.         divu.l    d2,d1:d4    ; d1=MOD(d1/d2) -> d1<d2
  52.  
  53.         move.l    d2,d5        ; init counter
  54.  
  55.         bra.s    loopentrym8    ; enter loop
  56. outerloopm8    swap    d0
  57.  
  58. innerloopm8    move.b    (a0),d3        ; get UBYTE
  59.         eor.b    #$80,d3        ; fix sign bit
  60.         move.b    d3,(a1)+    ; put BYTE
  61.  
  62.         add.l    d4,a0        ; add skip to source ptr
  63.  
  64.         sub.l    d1,d5        ; decrease counter
  65.         bgt.s    loopentrym8    ; skip if no underflow
  66.         addq.w    #1,a0        ; add 1 to source ptr
  67.         add.l    d2,d5        ; reset counter
  68.  
  69. loopentrym8    dbra    d0,innerloopm8    ; loop length
  70.         swap    d0
  71.         dbra    d0,outerloopm8
  72.  
  73.         movem.l    (sp)+,d3/d4/d5    ; restore registers
  74.         rts
  75.  
  76.         ; source and destination frequency are equal
  77.         ; use an optimized loop consisting of two parts
  78.  
  79. quickloopm8    movem.l    d3/d4,-(sp)    ; save registers
  80.  
  81.         move.l    #$80808080,d4    ; keep EOR value in d4 (faster!)
  82.  
  83.         move.l    d0,-(sp)    ; save length
  84.         lsr.l    #2,d0        ; divide length by 4
  85.         bra.s    quickentrym8    ; enter loop
  86. quickouterm8    swap    d0
  87.  
  88. quickinnerm8    move.l    (a0)+,d3    ; get ULONG
  89.         eor.l    d4,d3        ; fix sign bits
  90.         move.l    d3,(a1)+    ; put ULONG
  91.  
  92. quickentrym8    dbra    d0,quickinnerm8    ; loop length/4
  93.         swap    d0
  94.         dbra    d0,quickouterm8
  95.  
  96.         move.l    (sp)+,d0    ; get length
  97.         and.l    #$3,d0        ; calc length MOD 4
  98.         bra.s    restentrym8    ; enter loop
  99.  
  100. restloopm8    move.b    (a0)+,d3    ; get UBYTE
  101.         eor.b    d4,d3        ; fix sign bits
  102.         move.b    d3,(a1)+    ; put BYTE
  103.  
  104. restentrym8    dbra    d0,restloopm8    ; loop length MOD 4
  105.  
  106.         movem.l    (sp)+,d3/d4    ; restore registers
  107.         rts
  108.  
  109.  
  110. ; 8 bit unsigned STEREO -> 8 bit signed MONO conversion/stretching
  111. ; ================================================================
  112.  
  113.         ; a0=source
  114.         ; a1=destination
  115.         ; d0=destination length
  116.         ; d1=source frequency
  117.         ; d2=destination frequency
  118.  
  119.         XDEF _ConvertStereo8
  120.  
  121. _ConvertStereo8    cmp.l    d1,d2
  122.         beq.s    quickloops8
  123.  
  124.         ; source and destination frequency differ
  125.         ; use a scaling conversion loop
  126.  
  127.         movem.l    d3/d4/d5/d6,-(sp)    ; save registers
  128.  
  129.         move.l    d1,d4        ; calc skip value in d4
  130.         moveq    #0,d1        ; d4=d1/d2
  131.         divu.l    d2,d1:d4    ; d1=MOD(d1/d2) -> d1<d2
  132.  
  133.         lsl.l    #1,d4        ; multiply skip by 2 (stereo)
  134.  
  135.         move.l    d2,d5        ; init counter
  136.  
  137.         bra.s    loopentrys8    ; enter loop
  138. outerloops8    swap    d0
  139.  
  140. innerloops8    move.b    (a0),d3        ; get UBYTE
  141.         lsr.b    #1,d3        ; halve value
  142.         move.b    1(a0),d6    ; get UBYTE
  143.         lsr.b    #1,d6        ; halve value
  144.         add.b    d6,d3        ; add values
  145.         eor.b    #$80,d3        ; fix sign bit
  146.         move.b    d3,(a1)+    ; put BYTE
  147.  
  148.         add.l    d4,a0        ; add skip to source ptr
  149.  
  150.         sub.l    d1,d5        ; decrease counter
  151.         bgt.s    loopentrys8    ; skip if no underflow
  152.         addq.w    #2,a0        ; add 2 to source ptr (stereo)
  153.         add.l    d2,d5        ; reset counter
  154.  
  155. loopentrys8    dbra    d0,innerloops8    ; loop length
  156.         swap    d0
  157.         dbra    d0,outerloops8
  158.  
  159.         movem.l    (sp)+,d3/d4/d5/d6    ; restore registers
  160.         rts
  161.  
  162.         ; source and destination frequency are equal
  163.         ; use a quicker loop without scaling
  164.  
  165. quickloops8    movem.l    d3/d4/d6,-(sp)    ; save registers
  166.  
  167.         bra.s    quickentrys8    ; enter loop
  168. quickouters8    swap    d0
  169.  
  170. quickinners8    move.b    (a0)+,d3    ; get UBYTE
  171.         lsr.b    #1,d3        ; halve value
  172.         move.b    (a0)+,d6    ; get UBYTE
  173.         lsr.b    #1,d6        ; halve value
  174.         add.b    d6,d3        ; add values
  175.         eor.b    #$80,d3        ; fix sign bit
  176.         move.b    d3,(a1)+    ; put BYTE
  177.  
  178. quickentrys8    dbra    d0,quickinners8    ; loop length
  179.         swap    d0
  180.         dbra    d0,quickouters8
  181.  
  182.         movem.l    (sp)+,d3/d4/d6    ; restore registers
  183.         rts
  184.  
  185.  
  186.         END
  187.